/**
 * Created by meiguizhinian on 2018/6/20
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

ivy.UIBase = cc.Node.extend({
	_className:"ivy.UIBase",
	//js 版本不再调用init来初始化, 在create函数中调用init
	ctor : function () {
		this._super();
		this._childrenList = [];

		this._onExitDelegate = new ivy.Delegate();
		this._onEnterDelegate = new ivy.Delegate();
		this._onEnterActionStartDelegate = new ivy.Delegate();
		this._onOutActionStartDelegate = new ivy.Delegate();

		this._touchRect = cc.rect();
		this._srcRectInEditor = cc.rect();
		this._enterActionID = new ivy.IDBaseT();
		this._outActionID = new ivy.IDBaseT();
		this._srcPosition = cc.p();

		this.setCascadeColorAndOpacityEnabled(true);
	},

	onEnter : function () {
		this._super();
		this._onEnterDelegate.call();
	},

	onExit : function () {
		this._onExitDelegate.call();
		this._super();
		let um = ivy.UIManager.getInstance();
		um.removeUIRefreshFunction(this);
		um.removeUIRefreshByNameFunction(this);
	},

	removeFromParent : function (cleanup) {
		let parent = this.getParent();
		if (parent instanceof ivy.UIBase) {
			for (let i=0; i!==parent._childrenList.length; ++i) {
				if (parent._childrenList[i]===this) {
					parent._childrenList.slice(i);
					break;
				}
			}
		}
		this._super(cleanup);
	},

	setSwallowTouches : function (isSwallows) {
		if (this._touchListener)
			this._touchListener.setSwallowTouches(isSwallows);
	},

	isSwallowTouches : function () {
		if (this._touchListener)
			return this._touchListener.isSwallowTouches();
		return false;
	},
	/**
	 * setContentSize(width, height)
	 * setContentSize(size)
	 */
	setContentSize : function (size, height) {
		let size_;
		if (height === undefined) {
			size_ = size;
		} else {
			size_ = cc.size(size, height);
		}
		this._super(size_.width, size_.height);

		switch (this._anchorType) {
			case ivy.UIBase.UIAnchorType.eAnchorHV:
				this._touchRect = cc.rect(-size.width / 2.0, -size.height / 2.0, size.width, size.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorLT:
				this._touchRect = cc.rect(0, -size.height, size.width, size.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorLB:
				this._touchRect = cc.rect(0, 0, size.width, size.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorRT:
				this._touchRect = cc.rect(-size.width, -size.height, size.width, size.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorRB:
				this._touchRect = cc.rect(-size.width, 0, size.width, size.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorHT:
				this._touchRect = cc.rect(-size.width / 2.0, -size.height, size.width, size.height);
				break;
			case ivy.UIBase.UIAnchorType.eANchorHB:
				this._touchRect = cc.rect(-size.width / 2.0,0, size.width, size.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorLV:
				this._touchRect = cc.rect(0, -size.height/2.0, size.width, size.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorRV:
				this._touchRect = cc.rect(-size.width, -size.height/2.0, size.width, size.height);
				break;
			default:
				break;
		}
	},

	addElement : function (child) {
		//如果已存在父节点 则添加失败
		if (child.getParent())
			return;
		this._childrenList.push(child);
		this.addChild(child, child.getLayerID());
		//注意此处child的坐标已被设置为编辑器中控件的原始坐标
		let newPosInThis = this.convertToNodeSpace(child.getPosition());
		child.setPosition(newPosInThis);
		child.setSrcPosition(newPosInThis);
	},

	addChildAndAdaption : function (child, zOrder, selfadaption) {
		this.addChild(child, zOrder);
		if (selfadaption) {
			child.setScaleX(this.getContentSize().width / child.getContentSize().width);
			child.setScaleY(this.getContentSize().height / child.getContentSize().height);
		}
	},

	getTouchRect : function () {
		return this._touchRect;
	},

	getTouchRectInWorldTransform : function () {
		let touchRectWorld = null;
		let baseWorldPos = this.convertToWorldSpace(cc.p());
		switch (this._anchorType) {
			case ivy.UIBase.UIAnchorType.eAnchorHV:
				touchRectWorld = cc.rect(baseWorldPos.x-this._touchRect.width/2.0, baseWorldPos.y-this._touchRect.height/2.0, this._touchRect.width, this._touchRect.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorLT:
				touchRectWorld = cc.rect(baseWorldPos.x, baseWorldPos.y-this._touchRect.height, this._touchRect.width, this._touchRect.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorLB:
				touchRectWorld = cc.rect(baseWorldPos.x, baseWorldPos.y, this._touchRect.width, this._touchRect.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorRT:
				touchRectWorld = cc.rect(baseWorldPos.x-this._touchRect.width, baseWorldPos.y - this._touchRect.height, this._touchRect.width, this._touchRect.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorRB:
				touchRectWorld = cc.rect(baseWorldPos.x-this._touchRect.width, baseWorldPos.y, this._touchRect.width, this._touchRect.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorHT:
				touchRectWorld = cc.rect(baseWorldPos.x-this._touchRect.width/2.0, baseWorldPos.y - this._touchRect.height, this._touchRect.width, this._touchRect.height);
				break;
			case ivy.UIBase.UIAnchorType.eANchorHB:
				touchRectWorld = cc.rect(baseWorldPos.x-this._touchRect.width/2.0, baseWorldPos.y, this._touchRect.width, this._touchRect.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorLV:
				touchRectWorld = cc.rect(baseWorldPos.x, baseWorldPos.y-this._touchRect.height/2.0, this._touchRect.width, this._touchRect.height);
				break;
			case ivy.UIBase.UIAnchorType.eAnchorRV:
				touchRectWorld = cc.rect(baseWorldPos.x-this._touchRect.width, baseWorldPos.y-this._touchRect.height/2.0, this._touchRect.width, this._touchRect.height);
				break;
			default:
				touchRectWorld = cc.rect(0, 0, 0, 0);
				break;
		}
		return touchRectWorld;
	},

	setTouchEnterCallback : function (func) {
		this._touchEnterFunc = func;
	},

	setTouchingCallback : function (func) {
		this._touchingFunc = func;
	},

	setTouchEndCallback : function (func) {
		this._touchEndFunc = func;
	},

	setTouchDoubleCallback : function (func) {
		this._touchDoubleFunc = func;
	},

	setTouchCancelCallback : function (func) {
		this._touchCancelFunc = func;
	},

	getAnchorType : function() {
		return this._anchorType;
	},

	setAnchorType : function(type) {
		this._anchorType = type;
	},

	setSrcRect : function (rect) {
		this._srcRectInEditor = rect;
	},

	getSrcRect : function () {
		return this._srcRectInEditor;
	},

	getLayerID : function () {
		return this._layerIDInEditor;
	},

	getEnterActionID : function() {
		return this._enterActionID.getValue();
	},

	isEnterActionIDVaild : function() {
		return this._enterActionID.valid();
	},
	//入场动画程序介入添加动作接口
	runEnterActionBy : function (func) {
		if (ivy.UIManager.getInstance().isElementSkipEnterAction(this._formName, this._blockName)) {
			return;
		}
		this.resetToSrcPosition();
		let enterActionTAG = ivy.UIBase.CommonActionTAG.eEnterAction;
		this.stopActionByTag(enterActionTAG);
		let outActionTAG = ivy.UIBase.CommonActionTAG.eOutAction;
		this.stopActionByTag(outActionTAG);
		if (this._enterActionID.valid()) {
			ivy.CocosActionDataManager.getInstance().runActionByNodeBy(this, this._enterActionID.getValue(), func, enterActionTAG);
		} else {
			if (func) {
				this.runAction(func(null));
			}
		}
		for (let child of this._childrenList) {
			child.runEnterAction();
		}
		if (!this._onEnterActionStartDelegate.empty()) {
			this._onEnterActionStartDelegate.call(this);
		}
	},

	runEnterAction : function () {
		this.runEnterActionBy(null);
	},

	getOutActionID : function () {
		return this._outActionID.getValue();
	},

	isOutActionIDVaild : function () {
		return this._outActionID.valid();
	},
	//入场动画程序介入添加动作接口
	runOutActionBy : function (func) {
		if (ivy.UIManager.getInstance().isElementSkipOutAction(this._formName, this._blockName)) {
			return;
		}
		let enterActionTAG = ivy.UIBase.CommonActionTAG.eEnterAction;
		this.stopActionByTag(enterActionTAG);
		let outActionTAG = ivy.UIBase.CommonActionTAG.eOutAction;
		this.stopActionByTag(outActionTAG);
		if (this._outActionID.valid()) {
			ivy.CocosActionDataManager.getInstance().runActionByNodeBy(this, this._outActionID.getValue(), func, outActionTAG);
		} else {
			if (func) {
				this.runAction(func(null));
			}
		}
		for (let child of this._childrenList) {
			child.runOutAction();
		}
		if (!this._onOutActionStartDelegate.empty()) {
			this._onOutActionStartDelegate.call(this);
		}
	},
	runOutAction : function () {
		this.runOutActionBy(null);
	},

	isIgnoreTouchEventWhenActionRunning : function () {
		return this._ignoreTouchEventWhenActionRunning;
	},

	setIgnoreTouchEventWhenActionRunning : function (is) {
		this._ignoreTouchEventWhenActionRunning = is;
	},

	getBlockName : function () {
		return this._blockName;
	},

	getFormName : function () {
		return this._formName;
	},

	setSrcPosition : function (pos) {
		this._srcPosition = pos;
	},

	getSrcPosition : function (){
		return this._srcPosition;
	},

	resetToSrcPosition : function () {
		this.setPosition(this._srcPosition);
	},
	setUIElementName : function (formName, blockName) {
		this._formName = formName;
		this._blockName = blockName;
		let uiDataIndex = ivy.UIManager.getInstance().getUIDataIndexByName(formName, blockName);
		this._formIndex = uiDataIndex.formIndex;
		this._blockIndex = uiDataIndex.blockIndex;
	},
	//在子节点添加完毕时调用
	onChildCreateComplete : function () {},
	//返回释放时调用的委托接口
	onExitDelegate : function() {
		return this._onExitDelegate;
	},

	onEnterDelegate : function() {
		return this._onEnterDelegate;
	},

	/**
	 * getChileByName(blockname);
	 * getChileByName(blockname, T);
	 * getChileByName(formName, blockname);
	 * getChileByName(formName, blockname, T);
	 * */
	getChildByName : function(formName, blockName, T=ivy.UIBase) {
		if (typeof(blockName)==="string") {
			let result = this.findChildByName(formName, blockName);
			if (result) {
				if (result instanceof T) {
					return result;
				}
			}
		} else {
			T = blockName;
			blockName = formName;
			return this.getChildByName(this.getFormName(), blockName, T);
		}
		return null;
    },

    isTouchEnable : function () {
		return !!this._touchHideLayer;
    },

    setTouchEnable : function (e) {
	    if (e) {
		    if (this._touchHideLayer) {
			    this._releaseTouchHideLayer();
		    }
	    } else {
		    if (!this._touchHideLayer) {
			    let size = this.getContentSize();
			    this._touchHideLayer = cc.LayerColor(cc.color(0, 0, 0, 0), size.width, size.height);
			    this.addChild(this._touchHideLayer, 100000);
			    //this._touchHideLayer.setSwallowsTouches(true); 不需要翻译，在下面传递参数
			    let listener1 = cc.EventListener.create({
				    event : cc.EventListener.TOUCH_ONE_BY_ONE,
				    swallowTouches : true,
				    onTouchBegan : function (touch, event) {
					    event.stopPropagation();
					    return true;
				    }
			    });
			    cc.eventManager.addListener(listener1, this._touchHideLayer);
		    }
	    }
    },

    isInScreen : function () {
	    let windowPos = this._convertToWindowSpace(cc.p());
	    let size = this.getContentSize();
	    let r = cc.rect(windowPos.x, windowPos.y, size.width, size.height);
	    let gc = ivy.GlobleConfig.getInstance();
	    let screenRect = cc.rect(0, 0, gc.getScreenWidth(), gc.getScreenHeight());
	    return cc.rectIntersectsRect(r, screenRect);
    },
    //////////////////////////////////////////////////////////////////////////
    onEnterActionStartDelegate : function () {
        return this._onEnterActionStartDelegate;
    },

    onOutActionStartDelegate : function () {
        return this._onOutActionStartDelegate;
    },
    //////////////////////////////////////////////////////////////////////////
    setEnableUserTouch : function(touch) {
        this._enableUserTouch = touch;
    },
    getEnableUserTouch : function() {
		return this._enableUserTouch;
    },
    //////////////////////////////////////////////////////////////////////////
    addToChildrenList : function(node) {
        this._childrenList.push(node);
    },
    getChildrenList : function() {
        return this._childrenList;
    },
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////protected
    _touchHideLayer : null,
    findChildByName : function(formName, blockName) {
	    let uiDataIndex = ivy.UIManager.getInstance().getUIDataIndexByName(formName, blockName);
	    return this.findChildByIndex(uiDataIndex.formIndex, uiDataIndex.blockIndex);
	},
    findChildByIndex : function(formIndex, blockIndex) {
	    if (formIndex < 0 || blockIndex < 0) {
		    return null;
	    }
	    if (this._formIndex === formIndex && this._blockIndex === blockIndex) {
		    return this;
	    } else {
	    	for (let i=0; i!==this._childrenList.length; ++i) {
	    		let child = this._childrenList[i];
	    		let result = child.findChildByIndex(formIndex, blockIndex);
	    		if (result) {
	    			return result;
			    }
		    }
	    }
	    return null;
    },

    _anchorType : 0, // ivy.UIBase.UIAnchorType.eAnchorHV
    setTouchListener : function(l) {
        this._touchListener = l;
    },
    setCascadeColorAndOpacityEnabled : function (enable) {
        this.setCascadeColorEnabled(enable);
        this.setCascadeOpacityEnabled(enable);
    },
    //触摸监听器(注意只有单点触摸控件才会初始化此对象)
    _touchListener: null,
    _touchEnterFunc : null,
    _touchingFunc : null,
    _touchEndFunc : null,
    _touchDoubleFunc : null,
    _touchCancelFunc : null,

    _onEnterDelegate : null,//cc::Delegate<void, UIBase*>
    _onExitDelegate : null,//cc::Delegate<void, UIBase*>

    _onEnterActionStartDelegate : null,//cc::Delegate<void, UIBase*>
    _onOutActionStartDelegate : null,//cc::Delegate<void, UIBase*>

    //用于记录当前控件触摸区域 提高触摸时效率
    //在重载的setContentSize中更新
    _touchRect : null,
    _srcRectInEditor : null,
    //////////////////////////////////////////////////////////////////////////
    //当前控件在编辑器中的层ID
    _layerIDInEditor : -1,
    //进场ActionID
	_enterActionID : null,
    //出场ActionID
    _outActionID : null,
    //////////////////////////////////////////////////////////////////////////
    //一些控件需要在执行触摸展示事件时忽略新的按键事件进入
    _ignoreTouchEventWhenActionRunning : false,
    //////////////////////////////////////////////////////////////////////////
    _childrenList : null,
	_formName : "",
    _blockName : "",
    //对应的窗体和控件Index 只推荐在查找中使用 减少字符串比较的消耗
    _formIndex : -1,
    _blockIndex : -1,
    //////////////////////////////////////////////////////////////////////////
    _srcPosition : null,
    //////////////////////////////////////////////////////////////////////////
    _enableUserTouch : true,
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////private
    _releaseTouchHideLayer : function () {
	    let l = this._touchHideLayer;
	    this._touchHideLayer = null;
	    ivy.Tools.pushFunctionToCocosThread(function() {
		    l.removeFromParent();
	    });
    },
});

ivy.UIBase.create = function() {
	return new ivy.UIBase();
};

ivy.UIBase.TOUCH_MIN_VAILD_DIS = 20;

ivy.UIBase.CommonActionTAG = {
    eEnterAction : 100,
    eOutAction : 101,
    eMaxCheckShowPopUpFormAction : 102,
};

ivy.UIBase.TouchMode = {
    //单点触摸
    eSingleTouch : 0,
    //多点触摸
    eMulitTouch : 1,
};

ivy.UIBase.UIAnchorType = {
    eAnchorHV : 0,
    eAnchorLT : 1,
    eAnchorLB : 2,
    eAnchorRT : 3,
    eAnchorRB : 4,
    eAnchorHT : 5,
    eANchorHB : 6,
    eAnchorLV : 7,
    eAnchorRV : 8,
};